/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package swoole.client.java;


import java.io.*;
import java.net.*;
import java.util.HashMap;  
import java.util.Map;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;

/**
 *
 * @author wujiaheng
 */
public class SwooleClientJava {
    
    public static String Server = "127.0.0.1";
    
    public static int Port = 9800;
    
    public static String Module = "Home";
    
    public static String Controller = "Index";
    
    public static String Action = "index";
    
    public static String Method = "post";
    
    public static String sign_key = "123456aabbcc";
    
 
    public static <T> String sign(T message){
        String signstr = JSON.toJSONString(message) + sign_key;
        String sign = MD5Util.string2MD5(signstr);
        return sign;
    }
    
    public static <T> HashMap buildRequestPara(T message,int status,boolean cache) {
        HashMap send_data = new HashMap();
        send_data.put("status",0);
        send_data.put("info",message);
        send_data.put("cache",cache);
        send_data.put("sign",sign(message));
        return send_data;
    }
    
    public static <T> HashMap buildRequestPara(T message,int status) {
        return buildRequestPara(message,status,false);
    }
    
    public static <T> HashMap buildRequestPara(T message) {
        return buildRequestPara(message,0,false);
    }
    
    public static void map_dump(Map map){
        Set set = map.entrySet();
        for (Iterator it = set.iterator(); it.hasNext();) {
            Map.Entry entry = (Map.Entry) it.next();
            System.out.println(entry.getKey() + "=>" + entry.getValue());
        }
    }
    
    public static byte[] topack(int n) {
        byte[] b = new byte[4];
        b[3] = (byte) (n & 0xff);
        b[2] = (byte) (n >> 8  & 0xff);
        b[1] = (byte) (n >> 16 & 0xff);
        b[0] = (byte) (n >> 24 & 0xff);
        return b;
    }
    
    public static void set_Server(String _Server){
        Server = _Server;
    }
    
    public static void set_Port(int _Port){
        Port = _Port;
    }
    
    public static void set_Module(String _Module){
        Module = _Module;
    }
    
    public static void set_Controller(String _Controller){
        Controller = _Controller;
    }
    
    public static void set_Action(String _Action){
        Action = _Action;
    }
    
    public static void set_Method(String _Method){
        Method = _Method;
    }
    
    public static <T> String send(T parameter) throws IOException{
        
        
        Map parameters = buildRequestPara(parameter);
        
        Map para = new HashMap();
        para.put("Module", Module);
        para.put("Controller", Controller);
        para.put("Action", Action);
        para.put("Method", Method);
        para.put("Parameter", parameters);
        
//        map_dump(para);
        
        String json_para = JSON.toJSONString(para);
        
//        System.out.println(json_para);       
        
        
        byte[] para_byte = json_para.getBytes();
        
        
        byte[] para_compress_byte = ZLibUtils.compress(para_byte);    
        
        
        int para_len = para_compress_byte.length;
        
        
        byte[] para_len_byte = topack(para_len);
        
        String para_len_str = new String(topack(para_len));
        
//        String send = para_len_str + json_para;
        
        byte[] send = new byte[para_len_byte.length+para_compress_byte.length];
        
        for (int i = 0; i < send.length; i++) {
            if(i<para_len_byte.length){
                send[i]=para_len_byte[i];
            }else{
                send[i]=para_compress_byte[i-para_len_byte.length];
            }
        }
              
            Socket socket = new Socket(Server, Port);  
            
            // 向服务器端发送数据 
            OutputStream os =  socket.getOutputStream(); 
            os.write(send); 
            os.flush();
            
            

            // 接收服务器端数据 
            InputStream is = socket.getInputStream();//            
            ByteArrayOutputStream pack_outSteam = new ByteArrayOutputStream();  
//            
//            //取得包长度
            
            int pack_head_length = 4;            
            byte[] pack_length_buffer = new byte[pack_head_length];            
            is.read(pack_length_buffer, 0, pack_head_length);
            pack_outSteam.write(pack_length_buffer, 0, pack_head_length);        
            byte[] pack_length_out = pack_outSteam.toByteArray();
            
            byte[] a = new byte[pack_head_length];  
            int i = a.length - 1,j = a.length - 1;  
            for (; i >= 0 ; i--,j--) {//从b的尾部(即int值的低位)开始copy数据  
                if(j >= 0)  
                    a[i] = pack_length_out[j];  
                else  
                    a[i] = 0;//如果b.length不足4,则将高位补0  
            }
            
            int v0 = (a[0] & 0xff) << 24;//&0xff将byte值无差异转成int,避免Java自动类型提升后,会保留高位的符号位  
            int v1 = (a[1] & 0xff) << 16;  
            int v2 = (a[2] & 0xff) << 8;  
            int v3 = (a[3] & 0xff) ;  
            int pack_length = v0 + v1 + v2 + v3;  
            
      
//            System.out.println(pack_length);//   
            
            //取得返回内容
            ByteArrayOutputStream outSteam = new ByteArrayOutputStream();  
            byte[] return_buffer = new byte[pack_length];
            is.read(return_buffer, 0, pack_length);
            outSteam.write(return_buffer, 0, pack_length);  
            byte[] return_out = outSteam.toByteArray();
            
            byte[] output = ZLibUtils.decompress(return_out);    
            String outputStr = new String(output);
            
//            System.out.println(outputStr);//   
            
            
            socket.close();
            
            return outputStr;
        
        
    }
    
    
    
    
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {
        
        Map message = new HashMap();
        message.put("server", "SwiftEmployeeInfoSetMysqlQueue");
        message.put("autoack", true);
        message.put("original", false);
        
        set_Server("10.1.1.42");
        set_Port(9800);
        set_Module("Mc");
        set_Controller("Message");
        set_Action("get");
        String res = send(message);
        
        
        // TODO code application logic here
        System.out.println(res);
        
        return;
        
        
    }
    
}


